package com.wgcloud;

import com.wgcloud.entity.*;
import com.wgcloud.util.UUIDUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version v3.3
 * @ClassName: OshiUtil
 * @author: http://www.wgstart.com
 * @date: 2021年11月19日
 * @Description: Oshi工具类
 * @Copyright: 2017-2024 wgcloud. All rights reserved.
 */
public class OshiUtil {

    private static Logger logger = LoggerFactory.getLogger(OshiUtil.class);

    private static CommonConfig commonConfig = (CommonConfig) ApplicationContextHelper.getBean(CommonConfig.class);

    // 抽取的方法：创建进程信息的 Map
    private static Map<String, Object> createProcessInfoMap(OSProcess process, String hostName) {
        // 直接返回一个新的 LinkedHashMap
        return new LinkedHashMap<String, Object>() {{
            put("ipadress", hostName);
            put("name", process.getName());
            put("pid", process.getProcessID());
            put("path", process.getPath());
            put("commandLine", process.getCommandLine());
        }};
    }

    // private static Runtime r = Runtime.getRuntime();
    //Stream API 简化代码

    /**
     * 获取所有满足条件的进程信息
     * 该方法使用Stream API来过滤和收集系统中的进程信息，以简化代码并提高性能
     *
     * @param appName  应用程序名称，用于过滤进程如果为null或空字符串，则不进行过滤
     * @param hostName 主机名称，用于创建进程信息Map
     * @param appPath  应用程序路径，用于过滤进程如果为null或空字符串，则不进行过滤
     * @return 包含所有满足条件的进程信息的ArrayList，每个进程信息以Map形式表示
     */
    public static ArrayList<Map<String, Object>> getAllProcessesInfo(String appName, String hostName, String appPath) {
        // 判断 appName 和 appPath 是否为 null 或空字符串
        boolean isAppNameEmpty = (appName == null || appName.trim().isEmpty());
        boolean isAppPathEmpty = (appPath == null || appPath.trim().isEmpty());

        // 获取所有进程
        oshi.SystemInfo si = new SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        List<OSProcess> processes = os.getProcesses();

        // 使用 Stream API 过滤和收集进程信息,并行流提高性能
        return processes.parallelStream().filter(process -> {
                    // 判断是否匹配 appName 和 appPath
                    boolean matchAppName = isAppNameEmpty || process.getName().contains(appName.trim());
                    boolean matchAppPath = isAppPathEmpty || process.getPath().contains(appPath.trim());
                    return matchAppName && matchAppPath;
                }).map(process -> createProcessInfoMap(process, hostName.trim())) // 转换为 Map
                .collect(Collectors.toCollection(ArrayList::new)); // 收集到 ArrayList
    }

    // 获取客户端所有符合要求的进程信息
    /*public static ArrayList<Map<String, Object>> getAllProcessesInfo(String appName, String hostName, String appPath) {
        // 判断 appName 和 appPath 是否为 null 或空字符串
        boolean isAppNameEmpty = (appName == null || appName.trim().isEmpty());
        boolean isAppPathEmpty = (appPath == null || appPath.trim().isEmpty());
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        oshi.SystemInfo si = new SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        // 获取所有进程
        List<OSProcess> processes = os.getProcesses();
        if (isAppNameEmpty && isAppPathEmpty) {
            // 这个就是获取所有的进程信息
            for (OSProcess process : processes) {
                Map<String, Object> map = createProcessInfoMap(process, hostName); // 调用抽取的方法
                list.add(map);
            }
        } else if (!isAppNameEmpty && !isAppPathEmpty) {
            // 这个是两个都要判断的逻辑
            for (OSProcess process : processes) {
                if (process.getName().contains(appName) && process.getPath().contains(appPath)) {
                    Map<String, Object> map = createProcessInfoMap(process, hostName); // 调用抽取的方法
                    list.add(map);
                }
            }
        } else if (!isAppNameEmpty) {
            // 这个是AppName不为空，AppPath为空的逻辑
            for (OSProcess process : processes) {
                if (process.getName().contains(appName)) {
                    Map<String, Object> map = createProcessInfoMap(process, hostName); // 调用抽取的方法
                    list.add(map);
                }
            }
        } else {
            // 这个就是剩下的情况，也就是AppName为空，AppPath不为空的逻辑
            for (OSProcess process : processes) {
                if (process.getPath().contains(appPath)) {
                    Map<String, Object> map = createProcessInfoMap(process, hostName); // 调用抽取的方法
                    list.add(map);
                }
            }
        }
        return list;
    }*/

    public static String getStringBeforeDot(String input) {
        // 检查输入字符串是否为空
        if (input == null || input.isEmpty()) {
            return "";
        }

        // 查找最后一个 '.' 的位置
        int dotIndex = input.lastIndexOf('.');

        // 如果找不到 '.'，返回整个字符串
        if (dotIndex == -1) {
            return input;
        }

        // 返回 '.' 之前的部分
        return input.substring(0, dotIndex);
    }

    /**
     * 根据应用程序名称和进程ID获取应用程序的路径
     *
     * @param appName 应用程序的名称
     * @param appPid  应用程序的进程ID
     * @return 如果找到匹配的应用程序，则返回其路径；如果匹配到多个进程，则返回null
     */
    public static String getAppPath(String appName, String appPid) {
        // 处理xxx.xxx，只要.前面的xx
        appName = getStringBeforeDot(appName);
        // 创建 SystemInfo 对象--这里和实体类名字重复了，使用全限定名称
        oshi.SystemInfo si = new oshi.SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        // 定义一个数组，用于存储进程执行路径信息-自增数组
        ArrayList<String> appPIDPathList = new ArrayList<>();
        ArrayList<String> appPIDPathListByPID = new ArrayList<>(); // add:增加进程号匹配项
        // 获取所有进程
        List<OSProcess> processes = os.getProcesses();
        // 匹配进程号与进程名称，返回匹配的进程
        for (OSProcess process : processes) {
            if (process.getName().equals(appName) && process.getProcessID() == Integer.parseInt(appPid)) {
                return process.getPath();
            }
            if (process.getName().equals(appName)) {
                appPIDPathList.add(process.getPath());
            }
            if (process.getProcessID() == Integer.parseInt(appPid)) {
                appPIDPathListByPID.add(process.getPath());
            }
        }
        if (appPIDPathList.size() == 1) {
            return appPIDPathList.get(0);
        }
        if (appPIDPathListByPID.size() == 1) {
            return appPIDPathListByPID.get(0);
        }
        // 如果匹配到多个进程，则返回空值
        logger.warn("获取进程 ::{}::{} :: 的执行路径为空！", appName, appPid);
        return null;
    }

    /**
     * 获取应用程序的命令行
     *
     * @param appName 应用程序名称
     * @param appPid  应用程序进程ID
     * @return 应用程序的命令行，如果未找到匹配的进程则返回null
     */
    public static String getAppCommandLine(String appName, String appPid) {
        // 处理xxx.xxx，只要.前面的xx
        appName = getStringBeforeDot(appName);
        // 创建 SystemInfo 对象--这里和实体类名字重复了，使用全限定名称
        oshi.SystemInfo si = new oshi.SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        // 定义一个数组，用于存储进程执行路径信息-自增数组
        ArrayList<String> appPIDPathList = new ArrayList<>();
        ArrayList<String> appPIDPathListByPID = new ArrayList<>();// add:增加进程号匹配项
        // 获取所有进程
        List<OSProcess> processes = os.getProcesses();
        // 匹配进程号与进程名称，返回匹配的进程
        for (OSProcess process : processes) {
            if (process.getName().equals(appName) && process.getProcessID() == Integer.parseInt(appPid)) {
                return process.getCommandLine();
            }
            if (process.getName().equals(appName)) {
                appPIDPathList.add(process.getCommandLine());
            }
            if (process.getProcessID() == Integer.parseInt(appPid)) {
                appPIDPathListByPID.add(process.getCommandLine());
            }
        }
        if (appPIDPathList.size() == 1) {
            return appPIDPathList.get(0);
        }
        if (appPIDPathListByPID.size() == 1) {
            return appPIDPathListByPID.get(0);
        }
        // 如果匹配到多个进程，则返回空值
        logger.warn("获取进程 ::{}::{} :: 的命令行为空！", appName, appPid);
        return null;
    }

    /**
     * 根据应用名称和路径获取进程ID
     * 此方法旨在通过应用名称、应用路径和命令行参数来精确识别并返回进程ID
     * 它首先尝试通过所有三个参数的精确匹配来找到进程如果找不到精确匹配的进程，
     * 它将尝试通过应用名称、路径或命令行参数单独匹配如果只有一个匹配项，则返回该进程的ID
     * 如果没有找到任何匹配项或有多个匹配项，则返回null，并记录警告消息
     *
     * @param appName        应用名称，用于匹配进程名称
     * @param appPath        应用路径，用于匹配进程路径
     * @param appCommandLine 应用启动的命令行参数，用于匹配进程的命令行参数
     * @return 匹配条件的进程ID，如果没有找到则返回null
     */
    public static String getProcessIdByNameAndPath(String appName, String appPath, String appCommandLine) {
        appName = getStringBeforeDot(appName);
        oshi.SystemInfo si = new oshi.SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        // 定义一个数组，用于存储进程号信息-自增数组
        ArrayList<String> appPIDList = new ArrayList<>();
        ArrayList<String> appPathPIDList = new ArrayList<>();
        ArrayList<String> appCommandLinePIDList = new ArrayList<>();
        ArrayList<String> otherCircumstance = new ArrayList<>();
        ArrayList<String> otherCircumstance1 = new ArrayList<>();
        ArrayList<String> otherCircumstance2 = new ArrayList<>();
        // 获取所有进程
        List<OSProcess> processes = os.getProcesses();
        // 匹配进程名称和进程路径，返回匹配的进程号
        for (OSProcess process : processes) {
            if (process.getName().equals(appName) && process.getPath().equals(appPath) && process.getCommandLine().equals(appCommandLine)) {
                return String.valueOf(process.getProcessID());
            }
            if (process.getName().equals(appName)) {
                appPIDList.add(String.valueOf(process.getProcessID()));
            }
            if (process.getPath().equals(appPath)) {
                appPathPIDList.add(String.valueOf(process.getProcessID()));
            }
            if (process.getCommandLine().equals(appCommandLine)) {
                appCommandLinePIDList.add(String.valueOf(process.getProcessID()));
            }
            if (process.getName().equals(appName) && process.getPath().equals(appPath)) {
                otherCircumstance.add(String.valueOf(process.getProcessID()));
            }
            // add:增加两个匹配项
            if (process.getPath().equals(appPath) && process.getCommandLine().equals(appCommandLine)) {
                otherCircumstance1.add(String.valueOf(process.getProcessID()));
            }
            if (process.getName().equals(appName) && process.getCommandLine().equals(appCommandLine)) {
                otherCircumstance2.add(String.valueOf(process.getProcessID()));
            }
        }
        if (appPIDList.size() == 1) {
            return appPIDList.get(0);
        }
        if (appPathPIDList.size() == 1) {
            return appPathPIDList.get(0);
        }
        if (appCommandLinePIDList.size() == 1) {
            return appCommandLinePIDList.get(0);
        }
        if (otherCircumstance.size() == 1) {
            return otherCircumstance.get(0);
        }
        if (otherCircumstance1.size() == 1) {
            return otherCircumstance1.get(0);
        }
        if (otherCircumstance2.size() == 1) {
            return otherCircumstance2.get(0);
        }
        logger.warn("尝试重新获取进程 ::{} :: 的进程号为空！", appName);
        return null;
    }

    /**
     * 获取磁盘使用率-任务管理器的百分比，即时间占用百分比
     *
     * @param hal 硬件抽象层对象，用于获取磁盘信息
     * @return DiskIO对象，包含磁盘使用率的百分比信息
     */
    public static DiskIO DiskIoPer(HardwareAbstractionLayer hal) {
        DiskIO diskIO = new DiskIO();
        try {
            // 获取磁盘信息
            List<HWDiskStore> diskStores = new ArrayList<>(hal.getDiskStores());

            // 记录上一次的IO统计信息
            List<Long> previousTransferTime = new ArrayList<>();

            // 初始化上一次的IO统计信息
            for (HWDiskStore disk : diskStores) {
                previousTransferTime.add(disk.getTransferTime());
            }
            Thread.sleep(5000); // 每隔5秒计算一次

            // 获取当前的磁盘信息
            List<HWDiskStore> currentDiskStores = new ArrayList<>(hal.getDiskStores());

            // 计算所有磁盘的综合使用百分比
            long totalTransferTimeDelta = 0;
            for (int i = 0; i < currentDiskStores.size(); i++) {
                HWDiskStore disk = currentDiskStores.get(i);
                long currentTransferTime = disk.getTransferTime();
                long transferTimeDelta = currentTransferTime - previousTransferTime.get(i);
                totalTransferTimeDelta += transferTimeDelta;
            }

            long totalTimeDelta = 5000; // 假设5秒内的时间单位是5000毫秒
            double ioUsagePercentage = ((double) totalTransferTimeDelta / totalTimeDelta) * 100;
            // System.out.println("Total IO Usage Percentage: " + String.format("%.2f", ioUsagePercentage) + "%");

            // 清空所有变量
            diskStores.clear();
            currentDiskStores.clear();
            previousTransferTime.clear();
            diskIO.setID(UUIDUtil.getUUID());
            // diskIO.setCREATE_TIME(DateUtil.getNowTime());
            diskIO.setDiskIOPer(Math.abs(ioUsagePercentage)); // 修复磁盘使用率可能为负数的问题
            diskIO.setHostname(commonConfig.getBindIp());
            return diskIO;
        } catch (Exception e) {
            logger.error("获取磁盘使用率异常", e);
            return null;
        }
    }
/*
public static DiskIO DiskIoPer(HardwareAbstractionLayer hal) {
    DiskIO diskIO = new DiskIO();
    try {
        // 1. 记录开始时间和初始状态
        long startTime = System.currentTimeMillis();
        List<HWDiskStore> initialDisks = new ArrayList<>(hal.getDiskStores());

        // 存储每个磁盘的初始状态
        Map<String, DiskSnapshot> initialSnapshots = new HashMap<>();
        for (HWDiskStore disk : initialDisks) {
            initialSnapshots.put(disk.getName(), new DiskSnapshot(
                disk.getTransferTime(),
                disk.getCurrentQueueLength()
            ));
        }

        // 2. 等待采样间隔
        Thread.sleep(5000);

        // 3. 计算实际间隔时间（毫秒）
        long actualInterval = System.currentTimeMillis() - startTime;
        if (actualInterval <= 0) {
            actualInterval = 5000; // 防止除零错误
        }

        // 4. 获取当前状态并计算
        List<HWDiskStore> currentDisks = new ArrayList<>(hal.getDiskStores());
        double totalWeightedUsage = 0.0;
        int diskCount = 0;

        for (HWDiskStore currentDisk : currentDisks) {
            DiskSnapshot initial = initialSnapshots.get(currentDisk.getName());
            if (initial == null) {
                continue; // 忽略新出现的磁盘
            }

            // 计算时间差和队列长度
            long transferTimeDelta = currentDisk.getTransferTime() - initial.transferTime;
            int avgQueueLength = Math.max(1, (initial.queueLength + currentDisk.getCurrentQueueLength()) / 2);

            // 考虑并行因素的加权计算
            double diskUsage = ((double) transferTimeDelta / actualInterval) * 100;
            double weightedUsage = diskUsage / avgQueueLength;

            totalWeightedUsage += Math.min(100, weightedUsage); // 单盘不超过100%
            diskCount++;
        }

        // 5. 计算整体使用率（所有磁盘的平均值）
        double ioUsagePercentage = diskCount > 0 ? totalWeightedUsage / diskCount : 0;

        // 6. 设置结果
        diskIO.setID(UUIDUtil.getUUID());
        diskIO.setDiskIOPer(Math.min(100, Math.max(0, ioUsagePercentage))); // 限制在0-100%
        diskIO.setHostname(commonConfig.getBindIp());
        return diskIO;

    } catch (Exception e) {
        logger.error("获取磁盘使用率异常", e);
        return null;
    }
}

// 辅助类：存储磁盘快照信息
private static class DiskSnapshot {
    final long transferTime;
    final int queueLength;

    DiskSnapshot(long transferTime, int queueLength) {
        this.transferTime = transferTime;
        this.queueLength = queueLength;
    }
}
     */

    /**
     * 获取内存使用信息
     *
     * @return
     */
    public static MemState memory(GlobalMemory memory) throws Exception {
        MemState memState = new MemState();
        long total = memory.getTotal() / 1024L / 1024L;
        long free = memory.getAvailable() / 1024L / 1024L;
        double usePer = (double) (total - free) / (double) total;
        // 增加数据库字段内容-单位是MB
        memState.setTotal(String.valueOf(total));
        memState.setFree(String.valueOf(free));
        memState.setUsed(String.valueOf((total - free)));
        memState.setUsePer(FormatUtil.formatDouble(usePer * 100, 2));
        memState.setHostname(commonConfig.getBindIp());
        return memState;
    }


    /**
     * 获取cpu使用率，等待率，空闲率
     *
     * @return
     * @throws Exception
     */
    public static CpuState cpu(CentralProcessor processor) throws Exception {

        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // Wait a second...
        Util.sleep(1000);

        CpuState cpuState = new CpuState();
        cpuState.setSys(FormatUtil.formatDouble(processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100, 1));
        cpuState.setHostname(commonConfig.getBindIp());
        return cpuState;
    }

    /**
     * 获取操作系统信息
     *
     * @return
     * @throws Exception
     */
    public static com.wgcloud.entity.SystemInfo os(CentralProcessor processor, OperatingSystem os) throws Exception {
        com.wgcloud.entity.SystemInfo systemInfo = new com.wgcloud.entity.SystemInfo();
        systemInfo.setHostname(commonConfig.getBindIp());
        systemInfo.setCpuCoreNum(processor.getLogicalProcessorCount() + "");
        String cpuInfo = processor.toString();
        if (cpuInfo.indexOf("\n") > 0) {
            cpuInfo = cpuInfo.substring(0, cpuInfo.indexOf("\n"));
        }
        systemInfo.setCpuXh(cpuInfo);
        systemInfo.setVersion(os.toString());
        systemInfo.setVersionDetail(os.toString());
        systemInfo.setState("1");
        return systemInfo;
    }

    /**
     * 获取磁盘使用信息
     *
     * @throws Exception
     */
    public static List<DeskState> file(Timestamp t, FileSystem fileSystem) throws Exception {

        List<DeskState> list = new ArrayList<DeskState>();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            long usable = fs.getUsableSpace();
            long total = fs.getTotalSpace();

            DeskState deskState = new DeskState();
            deskState.setFileSystem(fs.getName());
            deskState.setHostname(commonConfig.getBindIp());
            deskState.setUsed(((total - usable) / 1024 / 1024 / 1024) + "G");
            deskState.setAvail((usable / 1024 / 1024 / 1024) + "G");
            deskState.setSize((total / 1024 / 1024 / 1024) + "G");
            double usedSize = (total - usable);
            double usePercent = 0;
            if (total > 0) {
                usePercent = FormatUtil.formatDouble(usedSize / total * 100D, 2);
            }
            deskState.setUsePer(usePercent + "%");
            deskState.setCreateTime(t);
            list.add(deskState);
        }

        return list;
    }

    /**
     * 获取系统负载
     *
     * @return
     */
    public static SysLoadState getLoadState(com.wgcloud.entity.SystemInfo systemInfo, CentralProcessor processor) throws Exception {
        SysLoadState sysLoadState = new SysLoadState();
        if (systemInfo == null) {
            return null;
        }
        if (systemInfo.getVersionDetail().indexOf("Microsoft") > -1) {
            //windows系统不支持负载指标
            return null;
        }
        double[] loadAverage = processor.getSystemLoadAverage(3);

        sysLoadState.setOneLoad(loadAverage[0]);
        sysLoadState.setHostname(commonConfig.getBindIp());
        sysLoadState.setFiveLoad(loadAverage[1]);
        sysLoadState.setFifteenLoad(loadAverage[2]);
        return sysLoadState;
    }


    /**
     * 获取进程信息
     *
     * @return
     */
    public static List<Object> getLoadPid(String pid, OperatingSystem os, GlobalMemory memory) throws Exception {

        try {
            List<Integer> pidList = new ArrayList<>();
            pidList.add(Integer.valueOf(pid));
            List<OSProcess> procs = os.getProcesses(pidList);

            for (int i = 0; i < procs.size() && i < 5; i++) {
                OSProcess p = procs.get(i);

                AppState appState = new AppState();
                appState.setCpuPer(FormatUtil.formatDouble(100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime(), 2));
                appState.setMemPer(FormatUtil.formatDouble(100d * p.getResidentSetSize() / memory.getTotal(), 2));
                String result = String.valueOf(100d * p.getResidentSetSize());
                System.out.println(100d * p.getVirtualSize());
                // 获取进程的句柄数和线程数
                long handleCount = p.getOpenFiles();
                int threadCount = p.getThreadCount();
                // System.out.println(handleCount + " " + threadCount+" ");

                double res1; //这个就获取了内存大小：KB
                try {
                    Double res = getDigitalTransformationMethods(result);
                    res1 = roundToTwoDecimalPlaces(res);
                } catch (Exception e) {
                    res1 = 10086.0;
                    logger.error("进程内存大小转化错误：", e);
                }
                List<Object> listPid = new ArrayList<>();
                listPid.add(appState);
                listPid.add(res1);
                listPid.add(handleCount);
                listPid.add(threadCount);
                return listPid;
            }

        } catch (Exception e) {
            logger.error("获取进程信息错误", e);
        }

        return null;
    }

    // 科学计数法转换为实际值的方法
    public static Double getDigitalTransformationMethods(String scientificNotation) throws Exception {
        // 判断是否包含科学计数法表示的数字,如果没有就直接返回原来的数字
        if (scientificNotation.contains("E")) {
            // System.out.println("转化百分数的逻辑");
            // 输出结果
            String[] parts = scientificNotation.split("E");
            double base = Double.parseDouble(parts[0]);
            int exponent = Integer.parseInt(parts[1]);
            // 计算实际值
            return base * Math.pow(10, exponent - 8) * 1024;
        } else {
            return Double.parseDouble(scientificNotation) / 1024 / 1024 * 10;
        }
    }

    // 保留两位小数的方法
    public static double roundToTwoDecimalPlaces(double number) {
        // 使用 BigDecimal 进行精确计算
        BigDecimal bigDecimal = new BigDecimal(Double.toString(number));

        // 如果小数部分小于 0.01，则将其四舍五入到 0.01
        if (bigDecimal.compareTo(new BigDecimal("0.01")) < 0) {
            return 0.01;
        }

        // 否则，将数字保留两位小数
        return bigDecimal.setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 获取网络带宽
     *
     * @param hal
     * @return
     * @throws Exception
     */
    public static NetIoState net(HardwareAbstractionLayer hal) throws Exception {
        long rxBytesBegin = 0;
        long txBytesBegin = 0;
        long rxPacketsBegin = 0;
        long txPacketsBegin = 0;
        long rxBytesEnd = 0;
        long txBytesEnd = 0;
        long rxPacketsEnd = 0;
        long txPacketsEnd = 0;
        List<NetworkIF> listBegin = hal.getNetworkIFs();
        for (NetworkIF net : listBegin) {
            rxBytesBegin += net.getBytesRecv();
            txBytesBegin += net.getBytesSent();
            rxPacketsBegin += net.getPacketsRecv();
            txPacketsBegin += net.getPacketsSent();
        }

        //暂停3秒
        Thread.sleep(5000);
        List<NetworkIF> listEnd = hal.getNetworkIFs();
        for (NetworkIF net : listEnd) {
            rxBytesEnd += net.getBytesRecv();
            txBytesEnd += net.getBytesSent();
            rxPacketsEnd += net.getPacketsRecv();
            txPacketsEnd += net.getPacketsSent();
        }

        long rxBytesAvg = (rxBytesEnd - rxBytesBegin) / 3 / 1024;
        long txBytesAvg = (txBytesEnd - txBytesBegin) / 3 / 1024;
        long rxPacketsAvg = (rxPacketsEnd - rxPacketsBegin) / 3 / 1024;
        long txPacketsAvg = (txPacketsEnd - txPacketsBegin) / 3 / 1024;
        NetIoState netIoState = new NetIoState();
        netIoState.setRxbyt(rxBytesAvg + "");
        netIoState.setTxbyt(txBytesAvg + "");
        netIoState.setRxpck(rxPacketsAvg + "");
        netIoState.setTxpck(txPacketsAvg + "");
        netIoState.setHostname(commonConfig.getBindIp());
        return netIoState;
    }
}
